//
//  NSThreadController.m
//  GCD
//
//  Created by 宜必鑫科技 on 2017/11/6.
//  Copyright © 2017年 宜必鑫科技. All rights reserved.
//  @synthesize  @property  表示的都是自动生成setter和getter方法
//  Masonry.h 必需先添加在适配
#import "NSThreadController.h"
#import <Masonry.h>
#import <ReactiveObjC.h>

@interface NSThreadController ()
@property (nonatomic, strong) NSString *name;
@property (atomic, strong) NSString *des;
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, assign) NSInteger totle;
@end

@implementation NSThreadController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self.view setBackgroundColor:[UIColor whiteColor]];
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"线程间的通信" forState:0];
    [self.view addSubview:button];
    [button mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(10);
        make.right.mas_equalTo(-10);
        make.top.mas_equalTo(100);
        make.height.mas_equalTo(50);
    }];
    [[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        [self NSThreadCommunication];
    }];
    
    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];
    button1.backgroundColor = [UIColor redColor];
    [button1 setTitle:@"线程安全" forState:0];
    [self.view addSubview:button1];
    [button1 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(10);
        make.right.mas_equalTo(-10);
        make.top.equalTo(button.mas_bottom).offset(10);
        make.height.mas_equalTo(50);
    }];
    [[button1 rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        [self safe];
    }];
    
    
    _imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 100, 100)];
    [self.view addSubview:_imageView];
    
    /**
       第一种创建方式 需要手动开启线程，可以拿到线程对象进行详细设置
     */
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:@"子线程1"];
    [thread start];
    /* 设置线程的属性 */
//    thread.name = @"哈哈哈";
    /* 设置线程的优先级 ,注意线程优先级的取值范围为0.0~1.0之间，1.0表示线程的优先级最高,如果不设置该值，那么理想状态下默认为0.5 */
//    thread.threadPriority = 1.0f;
    /* 退出当前线程 */
//    [NSThread exit];
    /* 阻塞线程 */
//    [NSThread sleepForTimeInterval:2.0];
//    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0f]];
    
    /* 线程安全 */
    // 多个线程访问同一个资源会发生数据安全问题
    // 解决方案使用互斥锁
    // 相关代码：@synchronized(self){}
    // 原子性和非原子性
    // 多个线程在写入原子属性时（调用 setter 方法），能够保证同一时间只有一个线程执行写入操作﻿
    // 原子属性的效率比互斥锁高，不过可能会出现脏数据﻿
    
    
    /**
       第二种创建方式 自动启动线程，无法对线程进行更详细的设置
     */
    [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:@"子线程2"];
    
    /**
       第三种创建方式 自动启动县城，无法进行更详细设置
     */
    [self performSelectorInBackground:@selector(run) withObject:@"子线程3"];
}


- (void)run
{
    for (int i = 0; i < 1000 ; i++)
    {
        int a = 1 + 1;
        NSLog(@"%d",a);
    }
}




- (void)NSThreadCommunication
{
    NSLog(@"点点点");
    [NSThread detachNewThreadSelector:@selector(downLoadImage) toTarget:self withObject:@"123"];
}


/**
   子线程
 */
- (void)downLoadImage
{
    CFTimeInterval start = CFAbsoluteTimeGetCurrent();
    
    NSURL *url = [NSURL URLWithString:@"http://p6.qhimg.com/t01d2954e2799c461ab.jpg"];
    NSData *imageData = [NSData dataWithContentsOfURL:url];
    UIImage *image = [UIImage imageWithData:imageData];
    //进入主线程 设置图片 如果设置为YES:等待当前线程执行完以后，主线程才会执行aSelector方法；
    [self performSelectorOnMainThread:@selector(setImageWith:) withObject:image waitUntilDone:YES];
    CFTimeInterval end = CFAbsoluteTimeGetCurrent();
    NSLog(@"第二步操作花费的时间为%f",end - start);
}

- (void)setImageWith:(UIImage *)image
{
    _imageView.image = image;
}




- (void)safe
{
    _totle = 100;
    NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(sellingTickets) object:nil];
    NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(sellingTickets) object:nil];
    NSThread *thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(sellingTickets) object:nil];
    thread1.name = @"售票员1";
    thread2.name = @"售票员2";
    thread3.name = @"售票员3";
    [thread1 start];
    [thread2 start];
    [thread3 start];
}

- (void)sellingTickets
{
    while (1) {
        // 创建对象
        // self.obj = [[NSObject alloc]init];
        // 锁对象，本身就是一个对象，所以self就可以了
        // 锁定的时候，其他线程没有办法访问这段代码
        @synchronized (self) {
            // 模拟售票时间，我们让线程休息0.05s
            [NSThread sleepForTimeInterval:0.05];
            if (_totle > 0) {
                _totle -= 1;
                NSLog(@"%@卖出了一张票，还剩下%zd张票",[NSThread currentThread].name,_totle);
            }else{
                NSLog(@"票已经卖完了");
                break;
            }
        }
    }
}

















- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end
